const { validteCreateUser, validateUserLogin } = require('../utils/validate/user.validate')
const HttpException = require('../exception/http.exception.js');
const User = require('../model/user')
const { md5Password, matchPassword } = require('../utils/md5')
const { sign } = require('../utils/jwt')
// 用户模块

//用户：创建（用户注册）
const createUser = async (req, res, next) => {
    console.log('------------creatUser---');
    try {
        console.log("createUser", req);
        //1获取数据 (email user password)
        let { email, username, password } = req.body.user

        // console.log("createUser", req.body);
        //2数据校验
        let { error, validate } = validteCreateUser(email, username, password)
        if (!validate) {
            throw new HttpException(401, '用户提交数据校验失败', error)
        }
        // console.log("111");
        //3业务验证
        //3.1)email 是否存在
        const existUser = await User.findByPk(email)
        if (existUser) {
            throw new HttpException(401, '用户邮箱已注册', error)
        }
        //    console.log("existUser",existUser);
        //3.2)username 是否唯一

        //4创建用户：用户信息存储到数据库
        //4.1密码加密：单向数据加密
        console.log("md5Password", md5Password(password));
        const md5pwd = md5Password(password)
        //4.2 user model 存储数据
        const user = await User.create({
            email,
            password: md5pwd,
            username,
        })
        console.log('用户注册', user);

        //5结果返回
        //5.1 成功=>next()
        let data = {}
        data.username = user.username
        data.email = user.email
        res.status(201)
            .json({
                status: 1,
                message: "注册成功",
                data
            })
    } catch (error) {//error 是一个HttpException实例
        //5.2 失败=>next(Httpcention实例对象)
        next(error)
    }
}
//用户：登录 token
const loginController = async (req, res, next) => {
    try {
        console.log("req.body",req.body);
        console.log("req.body.user",req.body.user);
        //01 authMiddleware 路由接口验证不需要
        //02 获取账号和密码
        let { email, password } = req.body.user
        console.log("req.body.user",req.body.user);
        //03 验证请求数据
        let { error, validate } = validateUserLogin(email, password)
        if (!validate) {
            throw new HttpException(401, '用户提交数据校验失败', error)
        }
        //04 业务逻辑
        //4.1）用户是否存在：数据库email账户是否存在=>user信息
        const user = await User.findByPk(email)
        if (!user) {
            throw new HttpException(401, '用户不存在', error)
        }

        //4.2)密码验证：123456 密码加密=>md5WD1 和email获取user.password=>md5PWD2对比

        let dbPWD = user.password;
        // console.log("password",user.password);
        const match = matchPassword(dbPWD, password);
        if (!match) {
            throw new HttpException(401, '用户密码不匹配', error)
        }
        //05)生成用户Token
        let username = user.username
        let token = await sign(username, email)

        //06 响应数据处理
        //两种方式:
        //数据字段少数据库数据=>准备新容器对象
        //数据字段多剔除敏感信息=>直接返回
        console.log(user.dataValues);
        delete user.dataValues.password
        user.dataValues.token = token
        //07 响应数据
        return res.status(200).json({
            status: 1,
            data: user.dataValues,
            message: '用户登录成功'
        })
    } catch (error) {
        next(error)
    }
}

//用户：获取
const getUserController = async (req, res, next) => {
    try {
        //--01 authMiddleware 路由接口验证需要
        //02获取数据 :req. email
        const { email } = req.user
        //03验证请求数据: email

        //04业务
        //4.1)根据email 获取user
        const user = await User.findByPk(email)
        if (!user) {
            throw new HttpException(401, '用户不存在', 'user not found')
        }
        //05:返回数据处理
        delete user.dataValues.password
        //5.1)敏感信息
        //5.2) token :如果token 不返回需要客户端缓存起来: localstorage
        // console.log("user",user);
        // user.dataValues.token = token
        //06)返回数据
        return res.status(200).json({
            status: 1,
            data: user.dataValues,
            message: '获取用户信息成功'
        })
    } catch (error) {
        next(error)
    }
}
//用户：更新
const updateUserController = async (req, res, next) => {
    try {
        //00 -- 需要authMiddleware认证
        //01获取数据: req. email
        const { email } = req.user
        //02 获取需要更新的用户:根据email
        const user = await User.findByPk(email)
        if (!user) {
            throw new HttpException(401, '用户不存在', 'user not found')
        }
        //03获取客户端提交修改数据: req. body. user
        //3.1)req. body.user存在判断=>没有修改数据判断
        const bodyUser = req.body.user
        if (!bodyUser) {
            throw new HttpException(401, '需要提交修改数据', 'update info is required')
        }
        //3.2)修改字段确定
        //老版本注意判断 underfind会覆盖
        // const username = bodyUser.username ? bodyUser.username : user.username
        // const bio = bodyUser.bio ? bodyUser.bio : user.bio
        // const avatar = bodyUser.avatar ? bodyUser.avatar : user.avatar
        //04 password处理=> 加密再更新
        // const password = bodyUser.password ? md5Password(bodyUser.password) : user.password

        //新版本
        const username = bodyUser.username
        const bio = bodyUser.bio
        const avatar = bodyUser.avatar
        const password = bodyUser.password ? md5Password(bodyUser.password) : undefined
        //05更新操作: user . update({字段: value,...})
        //5.1)先通过email找到email对应的用户记录=>更新字段；适合批量更新
        //类的静态方法
        // const updateUser=await User.update({username,bio,avatar,password},{
        //     where:{
        //         email
        //     }
        // })
        //实例方法
        const updateUser = await user.update({ username, bio, avatar, password })
        //console.log("updateUser",updateUser);
        //06更新结果:去除敏感信息/ token 是否添加
        //console.log(updateUser.username);  //get 可以get从dataValue获取  ；updateUser直接set字段 不生效；
        //console.log(await sign(updateUser.username, updateUser.email));
        delete updateUser.dataValues.password
        updateUser.dataValues.token = await sign(updateUser.username, updateUser.email)//使用dataValues.token追加到data中
        //07直接返回
        return res.status(200).json({
            status: 1,
            message: '更新成功',
            data: updateUser.dataValues//updateUser 和updateUser.dataValues都可以
        })
    } catch (error) {
        next(error)
    }

}
module.exports = { createUser, loginController, getUserController, updateUserController }




